// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: GPL-3.0-or-later

package xyz.apiote.bimba.czwek.data.settings

import android.content.Context
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.merge
import xyz.apiote.bimba.czwek.data.FeedInfoFlowItem
import xyz.apiote.bimba.czwek.data.sources.Server
import xyz.apiote.bimba.czwek.data.sources.feeds.FeedInfoOfflineDataSource
import xyz.apiote.bimba.czwek.data.sources.feeds.FeedsOfflineDataSource
import xyz.apiote.bimba.czwek.repo.FeedInfo
import xyz.apiote.bimba.czwek.settings.feeds.FeedSettings
import xyz.apiote.bimba.czwek.settings.feeds.FeedsSettings

class SettingsRepository {
	private val feedsSettingsOfflineDataSource = FeedsOfflineDataSource()
	private val feedInfosOfflineDataSource = FeedInfoOfflineDataSource()

	fun getAllFeeds(
		context: Context,
		serverID: String = Server.get(context).getSelectedServer().id()
	): FeedsSettings {
		return getServerFeeds(context, serverID)
			.copy(transitous = getTransitous(context))
			.copy(geocoding = getGeocoding(context))
	}

	fun getServerFeeds(
		context: Context,
		serverID: String = Server.get(context).getSelectedServer().id()
	): FeedsSettings {
		return FeedsSettings(feedsSettingsOfflineDataSource.getFeeds(serverID, context), null, null)
	}

	fun getTransitous(context: Context): FeedSettings? {
		return feedsSettingsOfflineDataSource.getTransitous(context)
	}

	fun getGeocoding(context: Context): FeedSettings? {
		return feedsSettingsOfflineDataSource.getGeocoding(context)
	}

	fun getGeocodingInfoShown(context: Context): Boolean {
		return feedsSettingsOfflineDataSource.getGeocodingInfoShown(context)
	}

	fun setGeocodingInfoShown(isShown: Boolean, context: Context) {
		return feedsSettingsOfflineDataSource.setGeocodingInfoShown(isShown, context)
	}

	fun getFeedInfos(context: Context): Flow<FeedInfoFlowItem> {
		val offlineFeedInfos = feedInfosOfflineDataSource.getFeedInfos(context)
		val onlineFeedInfos = Server.get(context).getFeedInfos(context)
		return listOf(
			onlineFeedInfos, offlineFeedInfos,
			flowOf(
				FeedInfo.getTransitous(context),
				FeedInfo.getGeocoding(context)
			)
		).merge()
	}

	fun getCachedFeedInfos(context: Context): Flow<FeedInfoFlowItem> {
		return listOf(feedInfosOfflineDataSource.getFeedInfos(context), flowOf(FeedInfo.getTransitous(context))).merge()
	}

	fun saveFeedsSettings(settings: FeedsSettings?, context: Context) {
		if (settings == null) {
			return
		}

		val serverID = Server.get(context).getSelectedServer().id()
		feedsSettingsOfflineDataSource.setFeeds(serverID, settings, context)
		settings.transitous?.let { feedsSettingsOfflineDataSource.setTransitous(it, context) }
		settings.geocoding?.let { feedsSettingsOfflineDataSource.setGeocoding(it, context) }
	}

	fun saveFeedInfos(feedInfos: Map<String, FeedInfo>, context: Context) {
		feedInfos.filter { (id, _) ->
			id != FeedInfo.ID_GEOCODING && id != FeedInfo.ID_TRANSITOUS
		}.forEach { (_, feedInfo) ->
			feedInfosOfflineDataSource.saveFeedInfo(feedInfo, context)
		}
	}
}